home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
-
- Cybergraphics Animation Viewer v1.2 1 Jun 1997
- -----------------------------------
-
- The files in this archive may be distributed anywhere provided they are
- unmodified and are not sold for profit.
-
- Ownership and copyright of all files remains with the author:
-
- Peter McGavin, 86 Totara Crescent, Lower Hutt, New Zealand.
- e-mail: peterm@maths.grace.cri.nz
-
- *****************************************************************************/
-
- #include "CyberAnim.h" /* separate file for GST */
-
- #include "unpack.h"
- #include "math64.h"
-
- #define NBITMAPS 2
-
- /****************************************************************************/
-
- #ifdef __SASC
- const char version[] = "$VER: CyberAnim 1.2 " __AMIGADATE__ ;
- long __oslibversion = 38; /* we require at least OS3.0 */
- char __stdiowin[] = "CON:20/50/500/130/CyberAnim";
- char __stdiov37[] = "/AUTO/CLOSE";
- #endif
-
- #ifndef max
- #define max(x,y) ((x)>=(y))?(x):(y)
- #endif
-
- char programname[20] = "CyberAnim";
- BPTR olddir = NULL;
- struct RDArgs *rdargs = NULL;
-
- /****************************************************************************/
-
- #define ID_ANIM MAKE_ID('A','N','I','M')
- #define ID_ILBM MAKE_ID('I','L','B','M')
- #define ID_ANHD MAKE_ID('A','N','H','D')
- #define ID_BMHD MAKE_ID('B','M','H','D')
- #define ID_CMAP MAKE_ID('C','M','A','P')
- #define ID_CAMG MAKE_ID('C','A','M','G')
- #define ID_BODY MAKE_ID('B','O','D','Y')
- #define ID_DLTA MAKE_ID('D','L','T','A')
-
- /* Masking techniques */
- #define mskNone 0
- #define mskHasMask 1
- #define mskHasTransparentColor 2
- #define mskLasso 3
- #define mskHasAlpha 4
-
- /* Compression techniques */
- #define cmpNone 0
- #define cmpByteRun1 1
- #define cmpByteRun2 2
-
- /* Bitmap header (BMHD) structure */
- struct BitMapHeader
- {
- UWORD bmh_Width; /* Width in pixels */
- UWORD bmh_Height; /* Height in pixels */
- WORD bmh_Left; /* Left position */
- WORD bmh_Top; /* Top position */
- UBYTE bmh_Depth; /* Number of planes */
- UBYTE bmh_Masking; /* Masking type */
- UBYTE bmh_Compression; /* Compression type */
- UBYTE bmh_Pad;
- UWORD bmh_Transparent; /* Transparent color */
- UBYTE bmh_XAspect;
- UBYTE bmh_YAspect;
- WORD bmh_PageWidth;
- WORD bmh_PageHeight;
- };
-
- /* Animation compression modes */
- #define cmpDirect 0
- #define cmpXor 1
- #define cmpLongdelta 2
- #define cmpShortdelta 3
- #define cmpDelta 4
- #define cmpBytedelta 5
- #define cmpStereo 6
- #define cmpAnim7 7
- #define cmpAnim8 8
- #define cmpJ 74
-
- /* Animation header flags */
- #define anfLongdata (1<<0)
- #define anfXor (1<<1)
- #define anfOnelist (1<<2)
- #define anfRLC (1<<3)
- #define anfVertical (1<<4)
- #define anfLongoffsets (1<<5)
-
- /* Animation header (ANHD) structure */
- struct AnimHeader
- {
- UBYTE anh_Operation; /* Compression method */
- UBYTE anh_Mask; /* plane mask (xor mode only) */
- UWORD anh_W, anh_H; /* w & h of body (xor mode only) */
- WORD anh_X, anh_Y; /* offset of body (xor mode only) */
- ULONG anh_Abstime; /* 1/60s sec relative to 1st frame */
- ULONG anh_Reltime; /* 1/60s sec relative to prev frame */
- UBYTE anh_Interleave; /* Modify frame this many back (0=2) */
- UBYTE anh_Pad0;
- ULONG anh_Bits; /* animation header flags */
- UBYTE anh_Pad[16];
- };
-
- struct mystream {
- FILE *f;
- UBYTE *rambuf;
- UBYTE *rambufptr;
- ULONG rambufsize;
- };
-
- struct options {
- BOOL ram;
- BOOL once;
- BOOL dbuf;
- BOOL warp;
- BOOL modereq;
- BOOL waittof;
- BOOL waitbovp;
- BOOL changescreenbuffer;
- BOOL loopframes;
- ULONG mode;
- };
-
- /****************************************************************************/
- /* resources (must be freed on exit) */
-
- struct Library *CyberGfxBase = NULL;
-
- static struct Screen *s = NULL;
- static struct Window *w = NULL;
-
- static struct ScreenBuffer *sb[2] = {NULL, NULL};
- static struct MsgPort *safeport = NULL;
- static struct MsgPort *dispport = NULL;
- static BOOL safe = TRUE;
- static BOOL disp = TRUE;
- static BOOL waited_until_safe = FALSE;
- static BOOL using_changescreenbuffer = FALSE;
- static BOOL using_waittof = FALSE;
- static BOOL using_waitbovp = FALSE;
-
- static struct BitMap *bm[NBITMAPS] = {NBITMAPS * NULL};
- static BOOL using_fastmem_bitmap = FALSE;
- static BOOL using_intermediate_buffer = FALSE;
- static WORD *dirty = NULL; /* min and max row changed for each 32 pixel col */
-
- static struct IFFHandle *iff = NULL;
- static BOOL iff_is_open = FALSE;
-
- static UWORD *emptypointer = NULL;
-
- static struct FileRequester *fr = NULL;
- static struct ScreenModeRequester *smr = NULL;
-
- struct Library *TimerBase = NULL;
- static struct MsgPort *timermp = NULL;
- static struct timerequest *timerio = NULL;
- static ULONG timerclosed = TRUE;
- static struct EClockVal *time = NULL;
- static struct EClockVal *time0 = NULL;
- static struct EClockVal *time1 = NULL;
- static double micros_per_eclock; /* Length of EClock tick in microseconds */
-
- static struct MsgPort *timermp2 = NULL;
- static struct timerequest *timerio2 = NULL;
- static ULONG timer2closed = TRUE;
-
- /****************************************************************************/
-
- static void wait_until_safe (void)
- {
- ULONG sig;
-
- if (!waited_until_safe) {
- /* Wait until beam has finished displayable bitmap for bm[].
- Need to wait for cybergraphics TOF here, but HOW????
- WaitTOF() appears to wait for custom chips which are different
- frequency and phase to cybergraphics display.
- Use 1/10 second timeout because sometimes changescreenbuffer msgs
- aren't replied to, e.g, when overscan HAM anim is dragged right down.
- */
- if (using_changescreenbuffer) {
- if (!safe) {
- timerio2->tr_node.io_Command = TR_ADDREQUEST;
- timerio2->tr_time.tv_secs = 0;
- timerio2->tr_time.tv_micro = 100000; /* 1/10 of a second */
- SendIO ((struct IORequest *)timerio2);
- sig = Wait ((1 << safeport->mp_SigBit) | (1 << timermp2->mp_SigBit));
- if ((sig & (1 << timermp2->mp_SigBit)) == 0) {
- AbortIO ((struct IORequest *)timerio2);
- Wait (1 << timermp2->mp_SigBit);
- } else
- printf ("Warning: ChangeScreenBuffer() succeeded but SafeMessage wasn't replied to!\n");
- while (GetMsg (safeport) != NULL) /* clear message queue */
- /* do nothing */ ;
- while (GetMsg (timermp2) != NULL) /* clear message queue */
- /* do nothing */ ;
- safe = TRUE;
- }
- } else if (using_waittof)
- WaitTOF ();
- else if (using_waitbovp)
- WaitBOVP (&s->ViewPort);
- waited_until_safe = TRUE;
- }
- }
-
- /****************************************************************************/
-
- static void wait_until_disp (void)
- /* Wait until it is safe to swap bitmaps without flicker */
- /* Use 1/10 second timeout because sometimes msgs aren't replied to! */
- {
- ULONG sig;
-
- if (using_changescreenbuffer) {
- if (!disp) {
- timerio2->tr_node.io_Command = TR_ADDREQUEST;
- timerio2->tr_time.tv_secs = 0;
- timerio2->tr_time.tv_micro = 100000; /* 1/10 of a second */
- SendIO ((struct IORequest *)timerio2);
- sig = Wait ((1 << dispport->mp_SigBit) | (1 << timermp2->mp_SigBit));
- if ((sig & (1 << timermp2->mp_SigBit)) == 0) {
- AbortIO ((struct IORequest *)timerio2);
- Wait (1 << timermp2->mp_SigBit);
- } else
- printf ("Warning: ChangeScreenBuffer() succeeded but DispMessage wasn't replied to!\n");
- while (GetMsg (dispport) != NULL) /* clear message queue */
- /* do nothing */ ;
- while (GetMsg (timermp2) != NULL) /* clear message queue */
- /* do nothing */ ;
- disp = TRUE;
- }
- }
- }
-
- /****************************************************************************/
-
- static void partial_cleanup (void)
- /* free resources allocated by animate_file() */
- {
- int i, plane;
-
- if (using_changescreenbuffer) {
- wait_until_safe ();
- wait_until_disp ();
- }
- if (iff_is_open) {
- CloseIFF (iff);
- iff_is_open = FALSE;
- }
- if (iff != NULL) {
- if (iff->iff_Stream != NULL) {
- if (((struct mystream *)iff->iff_Stream)->f != NULL)
- fclose (((struct mystream *)iff->iff_Stream)->f);
- if (((struct mystream *)iff->iff_Stream)->rambuf != NULL)
- free (((struct mystream *)iff->iff_Stream)->rambuf);
- free ((void *)iff->iff_Stream);
- }
- FreeIFF (iff);
- iff = NULL;
- }
- for (i = 0; i < NBITMAPS; i++) {
- if (!using_intermediate_buffer) {
- if (bm[i] != NULL)
- if (!using_changescreenbuffer)
- free (bm[i]);
- } else if (using_fastmem_bitmap) {
- if (bm[i] != NULL) {
- for (plane = 0; plane < bm[i]->Depth; plane++)
- if (bm[i]->Planes[plane] != NULL)
- free (bm[i]->Planes[plane]);
- free (bm[i]);
- }
- } else if (bm[i] != NULL)
- FreeBitMap (bm[i]);
- bm[i] = NULL;
- }
- if (dirty != NULL) {
- free (dirty);
- dirty = NULL;
- }
- if (w != NULL) {
- CloseWindow (w);
- w = NULL;
- }
- if (sb[1] != NULL) {
- FreeScreenBuffer (s, sb[1]);
- sb[1] = NULL;
- }
- if (sb[0] != NULL) {
- FreeScreenBuffer (s, sb[0]);
- sb[0] = NULL;
- }
- if (s != NULL) {
- CloseScreen (s);
- s = NULL;
- }
- if (dispport != NULL) {
- DeletePort (dispport);
- dispport = NULL;
- }
- if (safeport != NULL) {
- DeletePort (safeport);
- safeport = NULL;
- }
- if (emptypointer != NULL) {
- FreeMem (emptypointer, 12);
- emptypointer = NULL;
- }
- }
-
- /****************************************************************************/
-
- static void cleanup (void)
- /* free all resources */
- {
- partial_cleanup ();
- if (IFFParseBase != NULL) {
- CloseLibrary ((struct Library *)IFFParseBase);
- IFFParseBase = NULL;
- }
- if (olddir != NULL) {
- CurrentDir (olddir);
- olddir = NULL;
- }
- if (rdargs != NULL) {
- FreeArgs (rdargs);
- rdargs = NULL;
- }
- if (time1 != NULL) {
- FreeMem (time1, sizeof(struct EClockVal));
- time1 = NULL;
- }
- if (time0 != NULL) {
- FreeMem (time0, sizeof(struct EClockVal));
- time0 = NULL;
- }
- if (time != NULL) {
- FreeMem (time, sizeof(struct EClockVal));
- time = NULL;
- }
- if (!timer2closed) {
- if (!CheckIO((struct IORequest *)timerio2)) {
- AbortIO ((struct IORequest *)timerio2);
- WaitIO ((struct IORequest *)timerio2);
- }
- CloseDevice ((struct IORequest *)timerio2);
- timer2closed = TRUE;
- }
- if (timerio2 != NULL) {
- DeleteExtIO ((struct IORequest *)timerio2);
- timerio2 = NULL;
- }
- if (timermp2 != NULL) {
- DeletePort (timermp2);
- timermp2 = NULL;
- }
- if (!timerclosed) {
- if (!CheckIO((struct IORequest *)timerio)) {
- AbortIO ((struct IORequest *)timerio);
- WaitIO ((struct IORequest *)timerio);
- }
- CloseDevice ((struct IORequest *)timerio);
- timerclosed = TRUE;
- TimerBase = NULL;
- }
- if (timerio != NULL) {
- DeleteExtIO ((struct IORequest *)timerio);
- timerio = NULL;
- }
- if (timermp != NULL) {
- DeletePort (timermp);
- timermp = NULL;
- }
- if (smr != NULL) {
- FreeAslRequest (smr);
- smr = NULL;
- }
- if (fr != NULL) {
- FreeAslRequest (fr);
- fr = NULL;
- }
- if (AslBase != NULL) {
- CloseLibrary ((struct Library *)AslBase);
- AslBase = NULL;
- }
- if (CyberGfxBase != NULL) {
- CloseLibrary ((struct Library *)CyberGfxBase);
- CyberGfxBase = NULL;
- }
- }
-
- /****************************************************************************/
- /* CTRL/C handler */
-
- #ifdef __SASC
- void _CXBRK (void)
- {
- cleanup ();
- fprintf (stderr, "**Break\n");
- exit (0);
- }
- #endif
-
- /****************************************************************************/
- /* Error handlers */
-
- static char bodystring[64];
-
- static struct TextAttr topaz80 = {
- "topaz.font", 8, 0, 0
- };
-
- static struct IntuiText bodytext[] = {
- {0, 1, JAM2, 10, 8, &topaz80, programname, &bodytext[1]},
- {0, 1, JAM2, 10, 20, &topaz80, bodystring, NULL},
- };
-
- static struct IntuiText negtext = {0, 1, JAM2, 6, 3, &topaz80, "Ok", NULL};
-
- static jmp_buf err_jmp;
-
- static void abort_anim (char *msg, ...)
- /* Exit animate_file() with message */
- {
- va_list arglist;
-
- va_start (arglist, msg);
- vsprintf (bodystring, msg, arglist);
- va_end (arglist);
- AutoRequest (w, &bodytext[0], NULL, &negtext, 0, 0, 320, 60);
- partial_cleanup (); /* free resources allocated by animate_file() */
- longjmp (err_jmp, 1); /* return from animate_file() */
- }
-
- static void die (char *msg, ...)
- /* Exit program with message, return code 10 */
- {
- va_list arglist;
-
- va_start (arglist, msg);
- vsprintf (bodystring, msg, arglist);
- va_end (arglist);
- AutoRequest (w, &bodytext[0], NULL, &negtext, 0, 0, 320, 60);
- cleanup ();
- exit (10);
- }
-
- /****************************************************************************/
- /* safe memory allocator */
-
- static void *malloc_check (size_t size)
- {
- void *p;
-
- if ((p = malloc (size)) == NULL)
- die ("Out of memory trying to allocate %ld bytes!", size);
- return (p);
- }
-
- /****************************************************************************/
-
- static void delay_until (struct EClockVal *next_time)
- /* delay until next_time or next intuievent or CTRL/C */
- /* (in the latter cases, abort the timer delay) */
- {
- ULONG sig;
-
- ReadEClock (time);
- if (cmp64 (time, next_time) > 0) {
- timerio->tr_node.io_Command = TR_ADDREQUEST;
- *(struct EClockVal *)&timerio->tr_time = *next_time;
- sub64 ((struct EClockVal *)&timerio->tr_time, time); /* timerio->tr_time -= time */
- BeginIO ((struct IORequest *)timerio); /* begin delay */
- sig = Wait ((1 << timermp->mp_SigBit) |
- (1 << w->UserPort->mp_SigBit) | /* also return for IDCMP */
- SIGBREAKF_CTRL_C); /* or SIGBREAKF_CTRL_C */
- if ((sig & (1 << timermp->mp_SigBit)) == 0) {
- SetSignal (sig, sig); /* restore IDCMP and SIGBREAKF_CTRL_C signals */
- AbortIO ((struct IORequest *)timerio);
- WaitIO ((struct IORequest *)timerio);
- }
- while (GetMsg (timermp) != NULL)
- /* nothing */ ;
- }
- ReadEClock (next_time);
- }
-
- /****************************************************************************/
-
- static char *mode_name (ULONG mode)
- /* Return a mode name for given mode, compatible with ASL mode requester */
- /* Use name in DisplayInfo database if available */
- /* else manually construct the name */
- {
- APTR handle;
- char *p;
- struct NameInfo nameinfo;
- struct DimensionInfo dimsinfo;
- static char modename[DISPLAYNAMELEN + 4 + 4 + 11 + 1];
-
- p = modename;
- *p = '\0';
- if ((handle = FindDisplayInfo (mode & ~SPRITES)) != NULL) {
- if (GetDisplayInfoData (handle, (UBYTE *)&nameinfo,
- sizeof(nameinfo), DTAG_NAME,
- NULL) > sizeof(struct QueryHeader)) {
- p += sprintf (p, "%s", nameinfo.Name);
- } else if (GetDisplayInfoData (handle, (UBYTE *)&dimsinfo,
- sizeof(dimsinfo), DTAG_DIMS,
- NULL) >= 66 /* sizeof(dimsinfo)*/) {
- switch (mode & MONITOR_ID_MASK) {
- case DEFAULT_MONITOR_ID:
- p += sprintf (p, "DEFAULT:"); /* PAL or NTSC??? */
- break;
- case NTSC_MONITOR_ID:
- p += sprintf (p, "NTSC:");
- break;
- case PAL_MONITOR_ID:
- p += sprintf (p, "PAL:");
- break;
- case VGA_MONITOR_ID:
- p += sprintf (p, "MULTISCAN:");
- break;
- case A2024_MONITOR_ID:
- p += sprintf (p, "A2024:");
- break;
- case PROTO_MONITOR_ID:
- p += sprintf (p, "PROTO:");
- break;
- case EURO72_MONITOR_ID:
- p += sprintf (p, "EURO72:");
- break;
- case EURO36_MONITOR_ID:
- p += sprintf (p, "EURO36:");
- break;
- case SUPER72_MONITOR_ID:
- p += sprintf (p, "SUPER72:");
- break;
- case DBLNTSC_MONITOR_ID:
- p += sprintf (p, "DBLNTSC:");
- break;
- case DBLPAL_MONITOR_ID:
- p += sprintf (p, "DBLPAL:");
- break;
- default:
- p += sprintf (p, "(unknown):");
- break;
- }
- p += sprintf (p, "%d x %d",
- dimsinfo.Nominal.MaxX - dimsinfo.Nominal.MinX + 1,
- dimsinfo.Nominal.MaxY - dimsinfo.Nominal.MinY + 1);
- if ((mode & HAM_KEY) != 0)
- p += sprintf (p, " HAM");
- if ((mode & EXTRAHALFBRITE_KEY) != 0)
- p += sprintf (p, " EHB");
- if ((mode & LACE) != 0)
- p += sprintf (p, " Interlaced");
- } else {
- p += sprintf (p, "%s", "(unnamed)");
- if ((mode & HAM_KEY) != 0)
- p += sprintf (p, " HAM");
- if ((mode & EXTRAHALFBRITE_KEY) != 0)
- p += sprintf (p, " EHB");
- if ((mode & LACE) != 0)
- p += sprintf (p, " Interlaced");
- }
- } else {
- p += sprintf (p, "%s", "(unavailable)");
- }
- return (modename);
- }
-
- /****************************************************************************/
-
- static ULONG parse_mode (char *modename)
- /* Modename may be descriptive name ("PAL Lores"), or hex ("$00420001" or */
- /* "0x12345678") or decimal ("32768"). */
- {
- ULONG mode, reason;
-
- mode = INVALID_ID;
- if (modename != NULL) {
- if (modename[0] == '0' && modename[1] == 'x') {
- if (sscanf (&modename[2], "%lx", &mode) != 1)
- mode = INVALID_ID;
- } else if (modename[0] == '$') {
- if (sscanf (&modename[1], "%lx", &mode) != 1)
- mode = INVALID_ID;
- } else if (modename[0] >= '0' && modename[0] <= '9') {
- if (sscanf (modename, "%ld", &mode) != 1)
- mode = INVALID_ID;
- } else {
- while ((mode = NextDisplayInfo (mode)) != INVALID_ID) {
- if ((mode & LORESDPF_KEY) == 0) {
- /* printf ("$%08x \"%s\"\n", mode, mode_name (mode)); */
- if (strcmp (mode_name (mode), modename) == 0)
- break;
- }
- }
- }
- }
- if (FindDisplayInfo (mode) == NULL)
- die ("ScreenMode not in database: \"%s\"", modename);
- if ((reason = ModeNotAvailable (mode)) != 0)
- die ("Mode $%08x is not available: %ld", mode, reason);
- return (mode);
- }
-
- /****************************************************************************/
-
- static void parse_tooltypes (char *fname, struct options *opt)
- /* set options according to icon tooltypes */
- {
- struct DiskObject *obj;
- char **toolarray, *s;
-
- if ((obj = GetDiskObject (fname)) != NULL) {
- toolarray = obj->do_ToolTypes;
- if (FindToolType (toolarray, "DISK") != NULL)
- opt->ram = FALSE;
- if (FindToolType (toolarray, "RAM") != NULL)
- opt->ram = FALSE;
- if (FindToolType (toolarray, "ONCE") != NULL)
- opt->once = TRUE;
- if (FindToolType (toolarray, "WARP") != NULL)
- opt->warp = TRUE;
- if (FindToolType (toolarray, "NOMODEREQ") != NULL)
- opt->modereq = FALSE;
- if (FindToolType (toolarray, "WAITTOF") != NULL)
- opt->waittof = TRUE;
- if (FindToolType (toolarray, "WAITBOVP") != NULL)
- opt->waitbovp = TRUE;
- if (FindToolType (toolarray, "CHANGESCREENBUFFER") != NULL)
- opt->changescreenbuffer = TRUE;
- if (FindToolType (toolarray, "LOOPFRAMES") != NULL)
- opt->loopframes = FALSE;
- if ((s = FindToolType (toolarray, "SCREENMODE")) != NULL)
- opt->mode = parse_mode (s);
- FreeDiskObject (obj);
- }
- }
-
- /****************************************************************************/
-
- static ULONG *calc_cmap (struct Screen *s, UBYTE *cmap, int ncolours,
- ULONG intended_mode)
- /* cmap is in ILBM format */
- /* Allocate and return structure in format for LoadRGB32() */
- {
- int c;
- ULONG *colourtable;
-
- colourtable = (ULONG *)malloc_check ((1 + 3 * ncolours + 1) * sizeof(ULONG));
- colourtable[0] = (ncolours << 16) + 0;
- for (c = 0; c < ncolours; c++) {
- colourtable[3 * c + 1] = *cmap++ * 0x01010101;
- colourtable[3 * c + 2] = *cmap++ * 0x01010101;
- colourtable[3 * c + 3] = *cmap++ * 0x01010101;
- }
- if ((intended_mode & EXTRAHALFBRITE_KEY) != 0) {
- cmap -= 3 * ncolours;
- for (c = ncolours >> 1; c < ncolours; c++) {
- colourtable[3 * c + 1] = (cmap[0] >> 1) * 0x01010101;
- colourtable[3 * c + 2] = (cmap[1] >> 1) * 0x01010101;
- colourtable[3 * c + 3] = (cmap[2] >> 1) * 0x01010101;
- cmap += 3;
- }
- }
- colourtable[1 + 3 * ncolours] = 0;
- return (colourtable);
- }
-
- /****************************************************************************/
-
- static BOOL unpackrow (BYTE **src0, BYTE *dst, WORD dstbytes)
- {
- BYTE *src;
- BYTE n;
- BOOL err;
-
- err = TRUE;
- src = *src0;
- while (dstbytes > 0) {
- n = *src++;
- if (n >= 0) {
- n += 1;
- if ((dstbytes -= n) < 0)
- goto error;
- memcpy (dst, src, n);
- src += n;
- } else if (n != -128) {
- n = 1 - n;
- if ((dstbytes -= n) < 0)
- goto error;
- memset (dst, *src++, n);
- }
- dst += n;
- }
- err = FALSE;
- error:
- *src0 = src;
- return (err);
- }
-
- /****************************************************************************/
-
- static void unpacklongdelta (WORD *wdata, LONG *plane, WORD bytesperrow,
- WORD *dirty)
- {
- WORD offset;
- UWORD count;
-
- while ((offset = *wdata++) != -1) {
- if (offset >= 0) {
- plane += offset;
- *plane = *(LONG *)wdata;
- wdata += 2;
- } else {
- count = *(UWORD *)wdata;
- wdata++;
- plane += -offset - 1;
- memcpy (plane, wdata, count << 2);
- plane += count - 1;
- wdata += (count << 1);
- }
- }
- }
-
- /****************************************************************************/
-
- static void unpackshortdelta (WORD *wdata, WORD *plane, WORD bytesperrow,
- WORD *dirty)
- {
- WORD offset;
- UWORD count;
-
- while ((offset = *wdata++) != -1) {
- if (offset >= 0) {
- plane += offset;
- *plane = *wdata++;
- } else {
- /*
- plane += -offset - 1;
- for (count = *wdata++; count > 0; count--)
- *plane++ = *wdata++;
- plane--;
- */
- count = *(UWORD *)wdata;
- wdata++;
- plane += -offset - 1;
- memcpy (plane, wdata, count << 1);
- plane += count - 1;
- wdata += count;
- }
- }
- }
-
- /****************************************************************************/
-
- #if 0
- void __asm unpackbytedelta (register __a0 BYTE *bdata,
- register __a1 PLANEPTR plane,
- register __d0 WORD bytesperrow,
- register __a2 WORD *dirty);
-
- static void unpackbytedelta (BYTE *bdata, PLANEPTR plane, WORD bytesperrow,
- WORD *dirty)
- {
- WORD x, y, count, w, first, last;
- BYTE *bp;
- UBYTE ub;
-
- for (x = 0; x < bytesperrow; x++) {
- first = -1;
- last = -1;
- bp = &plane[x];
- y = 0;
- for (count = *bdata++; count > 0; count--) {
- if ((w = *bdata++) > 0) {
- y += w;
- bp += w * bytesperrow;
- } else if (w < 0) {
- if (first < 0)
- first = y;
- last = (y += (w &= 0x7f));
- for ( ; w > 0; w--) {
- *bp = *bdata++;
- bp += bytesperrow;
- }
- } else /* w == 0 */ {
- if (first < 0)
- first = y;
- last = (y += (ub = (UBYTE)*bdata++));
- w = *bdata++;
- for ( ; ub > 0; ub--) {
- *bp = w;
- bp += bytesperrow;
- }
- }
- }
- if (first >= 0 && (dirty[0] < 0 || first < dirty[0]))
- dirty[0] = first;
- if (last >= 0 && (dirty[1] < 0 || last > dirty[1]))
- dirty[1] = last;
- if ((x & 3) == 3)
- dirty += 2;
- }
- }
- #endif
-
- /****************************************************************************/
-
- #if 0
- static void unpackanim7word (BYTE *bdata, WORD *data, PLANEPTR plane,
- WORD wordsperrow, WORD *dirty)
- {
- WORD x, y, count, w, first, last;
- WORD *wp;
- UBYTE ub;
-
- for (x = 0; x < wordsperrow; x++) {
- first = -1;
- last = -1;
- wp = &((WORD *)plane)[x];
- y = 0;
- for (count = *bdata++; count > 0; count--) {
- if ((w = *bdata++) > 0) {
- y += w;
- wp += w * wordsperrow;
- } else if (w < 0) {
- if (first < 0)
- first = y;
- last = (y += (w &= 0x7f));
- for ( ; w > 0; w--) {
- *wp = *data++;
- wp += wordsperrow;
- }
- } else /* w == 0 */ {
- if (first < 0)
- first = y;
- last = (y += (ub = (UBYTE)*bdata++));
- w = *data++;
- for ( ; ub > 0; ub--) {
- *wp = w;
- wp += wordsperrow;
- }
- }
- }
- if (first >= 0 && (dirty[0] < 0 || first < dirty[0]))
- dirty[0] = first;
- if (last >= 0 && (dirty[1] < 0 || last > dirty[1]))
- dirty[1] = last;
- if ((x & 1) == 1)
- dirty += 2;
- }
- }
- #endif
-
- /****************************************************************************/
-
- #if 0
- void __asm unpackanim7long (register __a0 BYTE *bdata,
- register __a4 LONG *data,
- register __a1 PLANEPTR plane,
- register __d0 WORD bytesperrow,
- register __a2 WORD *dirty);
-
- static void unpackanim7long (BYTE *bdata, LONG *data, PLANEPTR plane,
- WORD bytesperrow, WORD *dirty)
- {
- WORD x, y, count, w, first, last;
- LONG *lp, l;
- UBYTE ub;
-
- for (x = 0; x < bytesperrow; x += 4) {
- first = -1;
- last = -1;
- lp = &((LONG *)plane)[x];
- y = 0;
- for (count = *bdata++; count > 0; count--) {
- if ((w = *bdata++) > 0) {
- y += w;
- lp += w * (bytesperrow >> 2);
- } else if (w < 0) {
- if (first < 0)
- first = y;
- last = (y += (w &= 0x7f));
- for ( ; w > 0; w--) {
- *lp = *data++;
- lp += (bytesperrow >> 2);
- }
- } else /* w == 0 */ {
- if (first < 0)
- first = y;
- last = (y += (ub = (UBYTE)*bdata++));
- l = *data++;
- for ( ; ub > 0; ub--) {
- *lp = l;
- lp += (bytesperrow >> 2);
- }
- }
- }
- if (first >= 0 && (dirty[0] < 0 || first < dirty[0]))
- dirty[0] = first;
- if (last >= 0 && (dirty[1] < 0 || last > dirty[1]))
- dirty[1] = last;
- dirty += 2;
- }
- }
- #endif
-
- /****************************************************************************/
-
- static void blit_opt (struct BitMap *bm, struct RastPort *rp, WORD *dirty,
- int yoffset)
- /* Blit from bm to rp starting from yoffset.
- Try to minimise amount of data blitted using information in dirty.
- Conversely, try to reduce the number of blits.
- dirty contains min and max rows changed for each 32-pixel-wide column
- (or (-1,-1) for unchanged columns).
- */
- {
- WORD x, firstx, miny, maxy;
-
- firstx = -1;
- for (x = 0; x < bm->BytesPerRow; x += 4) {
- if (dirty[0] >= 0 && dirty[1] >= 0) {
- if (firstx == -1) {
- firstx = x;
- miny = dirty[0];
- maxy = dirty[1];
- } else if (abs(dirty[0] - miny) < 10 &&
- abs(dirty[1] - maxy) < 10) {
- miny = min(dirty[0], miny);
- maxy = max(dirty[1], maxy);
- } else {
- BltBitMapRastPort (bm, firstx << 3, miny, rp, firstx << 3,
- miny + yoffset, (x - firstx) << 3,
- maxy - miny, 0xc0);
- firstx = x;
- miny = dirty[0];
- maxy = dirty[1];
- }
- } else if (firstx != -1) {
- BltBitMapRastPort (bm, firstx << 3, miny, rp, firstx << 3,
- miny + yoffset, (x - firstx) << 3,
- maxy - miny, 0xc0);
- firstx = -1;
- }
- dirty += 2;
- }
- if (firstx != -1)
- BltBitMapRastPort (bm, firstx << 3, miny, rp, firstx << 3,
- miny + yoffset, (bm->BytesPerRow - firstx) << 3,
- maxy - miny, 0xc0);
- }
-
- /****************************************************************************/
-
- #if 0
- static void PrintTopChunk (struct IFFHandle *iff)
- {
- struct ContextNode *top;
- short i;
- char idbuf[5];
-
- /* Get a pointer to the context node describing the current context. */
- if (!(top = CurrentChunk (iff)))
- return;
-
- /*
- * Print a series of dots equivalent to the current nesting depth of chunks processed so far.
- * This will cause nested chunks to be printed out indented.
- */
- for (i = iff->iff_Depth; i--; )
- printf (". ");
-
- /* Print out the current chunk's ID and size. */
- printf ("%s %ld ", IDtoStr (top->cn_ID, idbuf), top->cn_Size);
-
- /* Print the current chunk's type, with a newline. */
- puts (IDtoStr (top->cn_Type, idbuf));
- }
- #endif
-
- /****************************************************************************/
- /* stream handler for iffparse allows reading from disk or ram */
-
- #ifdef __SASC
- static __saveds __asm LONG mystreamhandler (
- register __a0 struct Hook *hook,
- register __a2 struct IFFHandle *iff,
- register __a1 struct IFFStreamCmd *actionpkt)
- {
- #else /* gcc */
- static LONG mystreamhandler (void)
- {
- register struct Hook *hook __asm("a0");
- register struct IFFHandle *iff __asm("a2");
- register struct IFFStreamCmd *actionpkt __asm("a1");
- #endif
- struct mystream *s;
- LONG nbytes, error;
- UBYTE *buf;
-
- s = (struct mystream *)iff->iff_Stream;
- nbytes = actionpkt->sc_NBytes;
- buf = (UBYTE *)actionpkt->sc_Buf;
- switch (actionpkt->sc_Command) {
- case IFFCMD_READ:
- if (s->f != NULL)
- error = (fread (buf, 1, nbytes, s->f) != nbytes);
- else if (s->rambuf != NULL &&
- nbytes <= s->rambuf + s->rambufsize - s->rambufptr &&
- nbytes >= 0) {
- /* printf ("Reading %d from %d\n", nbytes, s->rambufptr - s->rambuf); */
- if (nbytes > 0) {
- memcpy (buf, s->rambufptr, nbytes);
- s->rambufptr += nbytes;
- }
- error = FALSE;
- } else
- error = TRUE;
- break;
- case IFFCMD_WRITE:
- if (s->f != NULL)
- error = (fwrite (buf, 1, nbytes, s->f) != nbytes);
- else
- error = TRUE;
- break;
- case IFFCMD_SEEK:
- if (s->f != NULL)
- error = (fseek (s->f, nbytes, SEEK_CUR) == -1);
- else if (s->rambuf != NULL) {
- s->rambufptr += nbytes;
- error = s->rambufptr > (s->rambuf + s->rambufsize) ||
- s->rambufptr < s->rambuf;
- } else
- error = TRUE;
- break;
- case IFFCMD_INIT:
- case IFFCMD_CLEANUP:
- error = FALSE;
- break;
- default:
- error = TRUE;
- }
- return (error);
- }
-
- static struct Hook mystreamhook = {
- {NULL},
- (ULONG (*)())mystreamhandler,
- NULL,
- NULL
- };
-
- /****************************************************************************/
-
- static ULONG __saveds __asm smr_filter (register __a0 struct Hook *smr_filter_hook,
- register __a2 struct ScreenModeRequester *smr,
- register __a1 ULONG mode)
- /* reject modes deeper than depth 8 */
- /* (because setting ASLSM_MaxDepth = 8 seems to be insufficient) */
- {
- UWORD count;
- struct DimensionInfo dimsinfo;
- void *handle;
-
- if ((handle = FindDisplayInfo (mode)) != NULL &&
- (count = GetDisplayInfoData (handle, (UBYTE *)&dimsinfo,
- sizeof(struct DimensionInfo), DTAG_DIMS,
- NULL)) < 66
- /* sizeof(struct DimensionInfo) */)
- abort_anim ("GetDisplayInfoData(Dims) failed (%d)", count);
- return (ULONG)(dimsinfo.MaxDepth <= 8);
- }
-
- /****************************************************************************/
-
- static void wait_for_click (void)
- /* wait for right mouse click or ESC or Q or CTRL/C */
- {
- struct IntuiMessage *msg;
- ULONG class, sig;
- UWORD code;
- BOOL going;
-
- going = TRUE;
- while (going) {
- sig = Wait ((1 << w->UserPort->mp_SigBit) | SIGBREAKF_CTRL_C);
- if ((sig & (1 << w->UserPort->mp_SigBit)) != 0) {
- while ((msg = (struct IntuiMessage *)GetMsg (w->UserPort)) != NULL) {
- class = msg->Class;
- code = msg->Code;
- ReplyMsg ((struct Message *)msg);
- switch (class) {
- case IDCMP_VANILLAKEY:
- switch (code) {
- case 0x03: /* CTRL/C */
- case 0x1b: /* ESC */
- case 'q': /* q */
- case 'Q': /* Q */
- going = FALSE;
- break;
- default:
- break;
- }
- break;
- case IDCMP_MOUSEBUTTONS:
- if (code == MENUDOWN)
- going = FALSE;
- break;
- default:
- break;
- }
- }
- }
- if ((sig & SIGBREAKF_CTRL_C) != 0)
- going = FALSE;
- }
- }
-
- /****************************************************************************/
-
- static void display_body (struct mystream *mystream, struct options *opt,
- struct BitMapHeader *bmhd, UBYTE *cmap,
- int width, int height, int oscan_height, int depth,
- char *fname, int which, ULONG intended_mode,
- struct EClockVal *eclocks,
- struct EClockVal *warp_eclocks,
- struct EClockVal *next_time)
- {
- ULONG size, *colourtable;
- UBYTE *body, *src, *dst[8];
- int plane, y, srcbytesperrow;
- struct BitMap *saved_bm;
-
- /* read body */
- size = CurrentChunk (iff)->cn_Size;
- if (mystream->f != NULL) {
- body = (UBYTE *)malloc_check (size);
- if (ReadChunkBytes (iff, body, size) != size)
- abort_anim ("Error reading %s", fname);
- } else
- body = mystream->rambufptr;
-
- /* wait until beam has finished displaying bm[which] */
- if (!using_intermediate_buffer)
- wait_until_safe ();
-
- /* render body to bm[which] */
- src = body;
- srcbytesperrow = RASSIZE (width, 1);
- for (plane = 0; plane < depth; plane++)
- dst[plane] = bm[which]->Planes[plane];
-
- for (y = 0; y < height; y++) {
- for (plane = 0; plane < depth; plane++) {
- switch (bmhd->bmh_Compression) {
- case cmpNone:
- memcpy (dst[plane], src, srcbytesperrow);
- src += srcbytesperrow;
- break;
- case cmpByteRun1:
- if (unpackrow ((BYTE **)&src, dst[plane], srcbytesperrow))
- abort_anim ("Error unpacking BODY");
- break;
- default:
- abort_anim ("Unrecognised compression");
- }
- dst[plane] += bm[which]->BytesPerRow;
- }
- }
-
- if (mystream->f != NULL)
- free (body);
-
- /* wait until beam has passed displayable bitmap associated with bm[which] */
- wait_until_safe ();
-
- /* copy bm[which] to its associated displayable bitmap */
- if (using_intermediate_buffer) {
- if (using_changescreenbuffer) {
- saved_bm = w->RPort->BitMap;
- w->RPort->BitMap = sb[which]->sb_BitMap;
- BltBitMapRastPort (bm[which], 0, 0, w->RPort, 0, 0, width, height, 0xc0);
- w->RPort->BitMap = saved_bm;
- } else
- BltBitMapRastPort (bm[which], 0, 0, w->RPort, 0,
- which == 0 ? 0 : oscan_height, width, height, 0xc0);
- }
-
- /* calculate colourtable */
- colourtable = calc_cmap (s, cmap, 1 << depth, intended_mode);
-
- /* wait for time between frames */
- delay_until (next_time);
- if (opt->warp)
- add64 (next_time, warp_eclocks);
- else
- add64 (next_time, eclocks);
-
- /* wait until previous frame has been displayed */
- if (using_changescreenbuffer)
- wait_until_disp ();
-
- /* load colourtable */
- LoadRGB32 (&s->ViewPort, colourtable);
-
- /* make bm[which] (or its associated displayable bitmap) visible */
- if (using_changescreenbuffer) {
- if (ChangeScreenBuffer (s, sb[which]) != 0) {
- disp = FALSE;
- safe = FALSE;
- }
- } else {
- /* MoveScreen (s, which != 0 ? oscan_height : -oscan_height, 0); */
- s->ViewPort.RasInfo->RyOffset = which != 0 ? oscan_height : 0;
- ScrollVPort (&s->ViewPort);
- }
- waited_until_safe = FALSE;
-
- free (colourtable);
-
- /* wait until beam has finished displaying bm[1 - which] */
- if (!using_intermediate_buffer)
- wait_until_safe ();
-
- /* copy bm[which] to bm[1 - which] */
- for (plane = 0; plane < depth; plane++)
- memcpy (bm[1 - which]->Planes[plane], bm[which]->Planes[plane],
- bm[which]->BytesPerRow * bm[which]->Rows);
-
- /* wait until beam past displayable bitmap associated with bm[1 - which] */
- wait_until_safe ();
-
- /* copy bm[1 - which] to its displayable bitmap (if bm[] not displayable) */
- if (using_intermediate_buffer) {
- if (using_changescreenbuffer) {
- saved_bm = w->RPort->BitMap;
- w->RPort->BitMap = sb[1 - which]->sb_BitMap;
- BltBitMapRastPort (bm[1 - which], 0, 0, w->RPort, 0, 0, width, height, 0xc0);
- w->RPort->BitMap = saved_bm;
- } else
- BltBitMapRastPort (bm[1 - which], 0, 0, w->RPort, 0,
- 1 - which == 0 ? 0 : oscan_height, width, height,
- 0xc0);
- }
- }
-
- /****************************************************************************/
-
- static void animate_file (char *fname, struct options opt)
- {
- int plane, i, width, height, oscan_height, depth, which, ifferror, oldpri;
- ULONG class, size, mode, intended_mode, totalframes, anh_bits, *colourtable;
- UWORD code, count, propertymask;
- WORD *wdata;
- UBYTE *dlta, anh_operation, anh_interleave;
- LONG fsize;
- void *handle;
- struct IntuiMessage *msg;
- BOOL going, first_time;
- struct StoredProperty *bmhdprop, *cmapprop, *camgprop, *anhdprop;
- struct BitMapHeader *bmhd;
- struct AnimHeader *anhd;
- struct DimensionInfo dimsinfo;
- struct mystream *mystream;
- char reqtitle[30], *type_string;
- struct EClockVal eclocks, warp_eclocks, total_eclocks, next_time;
- struct BitMap *saved_bm;
- static struct Hook smr_filter_hook = {
- {NULL},
- (ULONG (*)())smr_filter,
- NULL,
- NULL
- };
- static struct Rectangle rect;
-
-
- anh_operation = 0;
- anh_interleave = 0;
- anh_bits = 0;
-
- /* checkpoint for abort_anim() */
- if (setjmp (err_jmp) != 0)
- return;
-
- parse_tooltypes (fname, &opt);
-
- if ((iff = AllocIFF ()) == NULL)
- abort_anim ("AllocIFF() failed");
-
- mystream = (struct mystream *)malloc_check (sizeof(struct mystream));
- memset (mystream, 0, sizeof(struct mystream));
-
- if ((mystream->f = fopen (fname, "r")) == 0)
- abort_anim ("Can't open %s", fname);
- if (fseek (mystream->f, 0, SEEK_END) == -1 ||
- (fsize = ftell (mystream->f)) == -1)
- abort_anim ("Error seeking %s", fname);
- rewind (mystream->f);
-
- if (opt.ram && (mystream->rambuf = malloc (fsize)) != NULL) {
- if (fread (mystream->rambuf, 1, fsize, mystream->f) != fsize ||
- fclose (mystream->f) == EOF)
- abort_anim ("Error reading %s", fname);
- mystream->f = NULL;
- mystream->rambufptr = mystream->rambuf;
- mystream->rambufsize = fsize;
- } else {
- if (opt.ram)
- printf ("Not enough memory to play from RAM, playing from DISK instead\n");
- mystream->rambuf = NULL;
- }
-
- iff->iff_Stream = (ULONG)mystream;
- InitIFF (iff, IFFF_FSEEK | IFFF_RSEEK, &mystreamhook);
-
- if (OpenIFF (iff, IFFF_READ) != 0)
- abort_anim ("OpenIFF() failed");
- iff_is_open = TRUE;
-
- if (PropChunk (iff, ID_ILBM, ID_BMHD) != 0 ||
- PropChunk (iff, ID_ILBM, ID_ANHD) != 0 ||
- PropChunk (iff, ID_ILBM, ID_CMAP) != 0 ||
- PropChunk (iff, ID_ILBM, ID_CAMG) != 0 ||
- StopChunk (iff, ID_ILBM, ID_BODY) != 0)
- abort_anim ("Error calling PropChunk or StopChunk parsing %s", fname);
- if ((ifferror = ParseIFF (iff, IFFPARSE_SCAN)) != 0)
- abort_anim ("%s: IFF error %d parsing %s", programname, ifferror, fname);
- if ((bmhdprop = FindProp (iff, ID_ILBM, ID_BMHD)) == NULL ||
- (cmapprop = FindProp (iff, ID_ILBM, ID_CMAP)) == NULL)
- abort_anim ("%s: Missing BMHD or CMAP parsing %s", programname, fname);
-
- bmhd = (struct BitMapHeader *)bmhdprop->sp_Data;
-
- width = bmhd->bmh_Width;
- height = bmhd->bmh_Height;
- depth = bmhd->bmh_Depth;
- if ((camgprop = FindProp (iff, ID_ILBM, ID_CAMG)) != NULL)
- intended_mode = *(ULONG *)camgprop->sp_Data;
- else
- intended_mode = 0;
-
- /* display file attributes */
- printf ("\nFile = %s, size = %ld bytes\n", fname, fsize);
- printf ("Anim size %ux%ux%u\n", width, height, depth);
- printf ("Intended ModeID = $%08lx \"%s\"\n", intended_mode,
- mode_name (intended_mode));
-
- type_string = "";
- propertymask = DIPF_IS_EXTRAHALFBRITE | DIPF_IS_DUALPF | DIPF_IS_PF2PRI |
- DIPF_IS_HAM;
- if (camgprop != NULL &&
- (*(ULONG *)camgprop->sp_Data & EXTRAHALFBRITE_KEY) != 0) {
- /* printf (" (EXTRAHALFBRITE)"); */
- type_string = " EHB";
- propertymask &= ~DIPF_IS_EXTRAHALFBRITE;
- }
- if (camgprop != NULL &&
- (*(ULONG *)camgprop->sp_Data & HAM_KEY) != 0) {
- switch (depth) {
- case 6:
- /* printf (" (HAM)"); */
- type_string = " HAM6";
- break;
- case 8:
- /* printf (" (HAM8)"); */
- type_string = " HAM8";
- break;
- default:
- abort_anim ("HAM but not depth 6 or 8");
- }
- propertymask &= ~DIPF_IS_HAM;
- }
- /* printf ("\n"); */
-
- first_time = TRUE;
- warp_eclocks.ev_hi = 0;
- warp_eclocks.ev_lo = 0;
- eclocks.ev_hi = 0;
- eclocks.ev_lo = 0;
- total_eclocks.ev_hi = 0;
- total_eclocks.ev_lo = 0;
- if ((anhdprop = FindProp (iff, ID_ILBM, ID_ANHD)) != NULL) {
- anhd = (struct AnimHeader *)anhdprop->sp_Data;
- anh_operation = anhd->anh_Operation;
- anh_interleave = anhd->anh_Interleave;
- anh_bits = anhd->anh_Bits;
- eclocks.ev_lo = (ULONG)((1000000.0 / 60.0) * anhd->anh_Reltime /
- micros_per_eclock + 0.5);
- add64 (&total_eclocks, &eclocks);
- }
-
- if (opt.mode != INVALID_ID)
-
- mode = opt.mode;
-
- else {
-
- /* try to guess the best screen mode */
- if (CyberGfxBase != NULL)
- mode = BestCModeIDTags (CYBRBIDTG_NominalWidth, max(width, 320),
- CYBRBIDTG_NominalHeight, max(height, 200),
- CYBRBIDTG_Depth, max(depth, 4),
- TAG_DONE);
- else if (GfxBase->LibNode.lib_Version >= 39)
- mode = BestModeID (BIDTAG_NominalWidth, width,
- BIDTAG_NominalHeight, height,
- BIDTAG_Depth, depth,
- BIDTAG_DIPFMustNotHave, propertymask,
- TAG_DONE);
- else
- mode = 0;
-
- /* put up mode requester */
- if (opt.modereq) {
- sprintf (reqtitle, "%s %dx%d%s", programname, width, height, type_string);
- if (!AslRequestTags (smr,
- ASLSM_TitleText, (ULONG)reqtitle,
- ASLSM_InitialDisplayID, mode,
- ASLSM_MinWidth, width,
- ASLSM_MinHeight, height,
- ASLSM_MinDepth, depth,
- ASLSM_MaxDepth, 8,
- ASLSM_PropertyMask, propertymask,
- ASLSM_PropertyFlags, 0,
- ASLSM_FilterFunc, &smr_filter_hook,
- TAG_DONE))
- abort_anim ("ScreenMode requester failed or cancelled");
- mode = smr->sm_DisplayID;
- }
- }
-
- printf ("Using ModeID = $%08lx \"%s\"\n", mode, mode_name (mode));
-
- if ((handle = FindDisplayInfo (mode)) != NULL &&
- (count = GetDisplayInfoData (handle, (UBYTE *)&dimsinfo,
- sizeof(struct DimensionInfo), DTAG_DIMS,
- NULL)) < 66
- /* sizeof(struct DimensionInfo) */)
- abort_anim ("GetDisplayInfoData(Dims) failed (%d)", count);
-
- oscan_height = max(height, dimsinfo.MaxOScan.MaxY - dimsinfo.MaxOScan.MinY + 1);
-
- if (GfxBase->LibNode.lib_Version < 39 ||
- (CyberGfxBase != NULL && IsCyberModeID (mode)))
- opt.changescreenbuffer = FALSE;
- using_changescreenbuffer = opt.changescreenbuffer;
- using_waittof = opt.waittof;
- using_waitbovp = opt.waitbovp;
-
- rect.MinX = 0;
- rect.MaxX = width - 1;
- rect.MinY = 0;
- rect.MaxY = height - 1;
-
- if ((s = OpenScreenTags (NULL,
- SA_DisplayID, mode,
- SA_DClip, (ULONG)&rect,
- SA_Width, width,
- SA_Height, using_changescreenbuffer
- ? oscan_height
- : oscan_height << 1,
- SA_Depth, max (depth, 4),
- /* SA_Draggable,FALSE, */
- /* SA_AutoScroll,FALSE, */
- /* SA_Exclusive,TRUE, */
- SA_Quiet,TRUE,
- SA_Type, CUSTOMSCREEN,
- TAG_DONE)) == NULL)
- abort_anim ("Can't open Screen (mode $%08x, depth %d)", mode, max(depth, 4));
-
- colourtable = calc_cmap (s, (UBYTE *)cmapprop->sp_Data, 1 << depth,
- intended_mode);
- LoadRGB32 (&s->ViewPort, colourtable);
- free (colourtable);
-
- printf ("Screen size %ux%u\n", s->Width, s->Height);
-
- if ((w = OpenWindowTags (NULL,
- WA_Left, 0,
- WA_Top, 0,
- WA_Width, width,
- WA_Height, s->ViewPort.RasInfo->BitMap->Rows,
- WA_IDCMP, IDCMP_VANILLAKEY | IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS,
- WA_Flags, WFLG_ACTIVATE | WFLG_BORDERLESS | WFLG_RMBTRAP,
- WA_CustomScreen, s,
- TAG_DONE)) == NULL)
- abort_anim ("Can't open Window");
-
- emptypointer = (WORD *)AllocMem (12, MEMF_CHIP | MEMF_CLEAR);
- SetPointer (w, emptypointer, 1, 16, 0, 0);
-
- /* allocate ports for changescreenbuffer */
- if (using_changescreenbuffer) {
- if ((safeport = CreatePort (NULL, 0)) == NULL ||
- (dispport = CreatePort (NULL, 0)) == NULL)
- abort_anim ("Can't create port!");
- Signal (FindTask (NULL),
- (1 << safeport->mp_SigBit) | (1 << dispport->mp_SigBit));
- }
- waited_until_safe = FALSE;
-
- /* allocate bitmaps and screenbuffers */
- for (i = 0; i < NBITMAPS; i++) {
- if (CyberGfxBase != NULL && IsCyberModeID (GetVPModeID (&s->ViewPort))) {
- if (using_changescreenbuffer)
- abort_anim ("Internal error 1");
- using_fastmem_bitmap = TRUE;
- using_intermediate_buffer = TRUE;
- /* allocate separate bitmaps in fastmem for cybergraphics */
- bm[i] = malloc_check (sizeof(struct BitMap));
- memset (bm[i], 0, sizeof(struct BitMap));
- InitBitMap (bm[i], depth, width, height);
- for (plane = 0; plane < bm[i]->Depth; plane++)
- bm[i]->Planes[plane] = malloc_check (bm[i]->BytesPerRow * bm[i]->Rows);
- } else if (GfxBase->LibNode.lib_Version >= 39 &&
- (GetBitMapAttr (s->ViewPort.RasInfo->BitMap, BMA_FLAGS) &
- BMF_STANDARD) != 0 &&
- (GetBitMapAttr (s->ViewPort.RasInfo->BitMap, BMA_FLAGS) &
- BMF_INTERLEAVED) == 0) {
- using_fastmem_bitmap = FALSE;
- using_intermediate_buffer = FALSE;
- if (using_changescreenbuffer) {
- /* use screen's bitmap and allocate another bitmap for dbuf */
- if ((sb[i] = AllocScreenBuffer (s, NULL, i == 0 ? SB_SCREEN_BITMAP : 0)) == NULL)
- abort_anim ("Can't allocate structure for double buffering");
- sb[i]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = safeport;
- sb[i]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort = dispport;
- bm[i] = sb[i]->sb_BitMap;
- } else {
- /* bitmaps point to top and bottom halves of screen's bitmap */
- bm[i] = malloc_check (sizeof(struct BitMap));
- memset (bm[i], 0, sizeof(struct BitMap));
- bm[i]->BytesPerRow = s->ViewPort.RasInfo->BitMap->BytesPerRow;
- bm[i]->Rows = oscan_height;
- bm[i]->Flags = s->ViewPort.RasInfo->BitMap->Flags;
- bm[i]->Depth = s->ViewPort.RasInfo->BitMap->Depth;
- for (plane = 0; plane < bm[i]->Depth; plane++)
- bm[i]->Planes[plane] = &s->ViewPort.RasInfo->BitMap->Planes[plane]
- [i * bm[i]->BytesPerRow * oscan_height];
- }
- } else {
- using_fastmem_bitmap = FALSE;
- using_intermediate_buffer = TRUE;
- /* generic code for any gfx system --- use separate bitmaps */
- if ((bm[i] = AllocBitMap (width, height, depth, 0, NULL)) == NULL)
- abort_anim ("Can't allocate bitmap");
- if (using_changescreenbuffer) {
- if ((sb[i] = AllocScreenBuffer (s, NULL, i == 0 ? SB_SCREEN_BITMAP : 0)) == NULL)
- abort_anim ("Can't allocate structure for double buffering");
- sb[i]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = safeport;
- sb[i]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort = dispport;
- }
- }
- }
- printf ("Bitmap size %ux%ux%u\n", bm[0]->BytesPerRow << 3,
- bm[0]->Rows, bm[0]->Depth);
- if (!using_fastmem_bitmap)
- printf ("Using CHIPMEM\n");
- if (!using_intermediate_buffer)
- printf ("Using direct rendering\n");
- if (using_changescreenbuffer)
- printf ("Using ChangeScreenBuffer()\n");
-
- dirty = (WORD *)malloc_check ((((bm[0]->BytesPerRow + 3) >> 2) << 1)
- * sizeof(WORD));
-
- /* PrintTopChunk (iff); */
-
- /* read the start time */
- ReadEClock (time0);
- next_time = *time0;
- add64 (&next_time, &eclocks);
-
- if (!using_intermediate_buffer ||
- (anh_interleave != 1 || (anh_bits & anfXor) == 0))
- which = 1;
- else
- which = 0;
-
- display_body (mystream, &opt, bmhd, (UBYTE *)cmapprop->sp_Data, width, height,
- oscan_height, depth, fname, which, intended_mode,
- &eclocks, &warp_eclocks, &next_time);
-
- totalframes = 1;
- going = TRUE;
-
- /* loop for each frame */
- while (going) {
-
- /* check for input */
- while ((msg = (struct IntuiMessage *)GetMsg (w->UserPort)) != NULL) {
- class = msg->Class;
- code = msg->Code;
- ReplyMsg ((struct Message *)msg);
- switch (class) {
- case IDCMP_VANILLAKEY:
- switch (code) {
- case 0x03: /* CTRL/C */
- case 0x1b: /* ESC */
- case 'q': /* q */
- case 'Q': /* Q */
- going = FALSE;
- break;
- case 'l': /* l */
- case 'L': /* L */
- opt.loopframes = !opt.loopframes;
- break;
- default:
- break;
- }
- break;
- case IDCMP_RAWKEY:
- switch (code) {
- case 0x50: /* F1 */
- warp_eclocks.ev_lo = 0;
- opt.warp = TRUE;
- break;
- case 0x51: /* F2 */
- warp_eclocks.ev_lo = (ULONG)((1000000.0 / 60.0) / micros_per_eclock + 0.5);
- opt.warp = TRUE;
- break;
- case 0x52: /* F3 */
- warp_eclocks.ev_lo = (ULONG)((1000000.0 / 30.0) / micros_per_eclock + 0.5);
- opt.warp = TRUE;
- break;
- case 0x53: /* F4 */
- warp_eclocks.ev_lo = (ULONG)((1000000.0 / 24.0) / micros_per_eclock + 0.5);
- opt.warp = TRUE;
- break;
- case 0x54: /* F5 */
- warp_eclocks.ev_lo = (ULONG)((1000000.0 / 15.0) / micros_per_eclock + 0.5);
- opt.warp = TRUE;
- break;
- case 0x55: /* F6 */
- warp_eclocks.ev_lo = (ULONG)((1000000.0 / 12.0) / micros_per_eclock + 0.5);
- opt.warp = TRUE;
- break;
- case 0x56: /* F7 */
- warp_eclocks.ev_lo = (ULONG)((1000000.0 / 10.0) / micros_per_eclock + 0.5);
- opt.warp = TRUE;
- break;
- case 0x57: /* F8 */
- warp_eclocks.ev_lo = (ULONG)((1000000.0 / 5.0) / micros_per_eclock + 0.5);
- opt.warp = TRUE;
- break;
- case 0x58: /* F9 */
- warp_eclocks.ev_lo = (ULONG)(1000000.0 / micros_per_eclock + 0.5);
- opt.warp = TRUE;
- break;
- case 0x59: /* F10 */
- opt.warp = FALSE;
- break;
- default:
- break;
- }
- break;
- case IDCMP_MOUSEBUTTONS:
- if (code == MENUDOWN)
- going = FALSE;
- break;
- default:
- break;
- }
- }
-
- #ifdef __SASC
- chkabort ();
- #endif
-
- /* PrintTopChunk (iff); */
-
- while ((ifferror = ParseIFF (iff, IFFPARSE_RAWSTEP)) == IFFERR_EOC)
- /* do nothing */ ;
-
- /* check for end of file */
- if (ifferror == IFFERR_EOF) {
- if (opt.once)
- break; /* break out of while (going) */
- else {
- /* found end of file --- rewind and seek to 2nd DLTA */
- CloseIFF (iff);
- iff_is_open = FALSE;
- if (mystream->f != NULL)
- rewind (mystream->f);
- else if (mystream->rambuf != NULL)
- mystream->rambufptr = mystream->rambuf;
- else
- abort_anim ("Internal error");
- if (OpenIFF (iff, IFFF_READ) != 0)
- abort_anim ("OpenIFF() failed");
- iff_is_open = TRUE;
-
- if (opt.loopframes) {
-
- /* seek past body */
-
- if (StopChunk (iff, ID_ILBM, ID_BODY) != 0)
- abort_anim ("Error calling StopChunk parsing %s", fname);
- if ((ifferror = ParseIFF (iff, IFFPARSE_SCAN)) != 0)
- abort_anim ("IFF error %d parsing %s for BODY", ifferror, fname);
-
- if (anh_operation != cmpBytedelta || anh_interleave != 1) {/* if not animbrush */
-
- /* seek past first DLTA */
- while ((ifferror = ParseIFF (iff, IFFPARSE_RAWSTEP)) == IFFERR_EOC)
- /* do nothing */ ;
- if (StopChunk (iff, ID_ILBM, ID_DLTA) != 0)
- abort_anim ("Error calling StopChunk parsing %s", fname);
- if ((ifferror = ParseIFF (iff, IFFPARSE_SCAN)) != 0) {
- if (ifferror != IFFERR_EOF)
- abort_anim ("IFF error %d parsing %s for DLTA", ifferror, fname);
- else {
- /* static picture --- display BODY and wait for quit event */
- wait_for_click ();
- going = FALSE;
- }
- }
- }
-
- } else { /* no loop frames --- redisplay body */
-
- if (PropChunk (iff, ID_ILBM, ID_ANHD) != 0 ||
- PropChunk (iff, ID_ILBM, ID_BMHD) != 0 ||
- PropChunk (iff, ID_ILBM, ID_CMAP) != 0 ||
- StopChunk (iff, ID_ILBM, ID_BODY) != 0)
- abort_anim ("Error calling PropChunk or StopChunk parsing %s", fname);
- if ((ifferror = ParseIFF (iff, IFFPARSE_SCAN)) != 0)
- abort_anim ("%s: IFF error %d parsing %s", programname, ifferror, fname);
-
- if ((anhdprop = FindProp (iff, ID_ILBM, ID_ANHD)) != NULL) {
- anhd = (struct AnimHeader *)anhdprop->sp_Data;
- anh_operation = anhd->anh_Operation;
- anh_interleave = anhd->anh_Interleave;
- anh_bits = anhd->anh_Bits;
- eclocks.ev_lo = (ULONG)((1000000.0 / 60.0) * anhd->anh_Reltime /
- micros_per_eclock + 0.5);
- add64 (&total_eclocks, &eclocks);
- }
-
- if ((bmhdprop = FindProp (iff, ID_ILBM, ID_BMHD)) == NULL ||
- (cmapprop = FindProp (iff, ID_ILBM, ID_CMAP)) == NULL)
- abort_anim ("%s: Missing BMHD or CMAP parsing %s", programname, fname);
-
- bmhd = (struct BitMapHeader *)bmhdprop->sp_Data;
-
- /* render to the other bitmap */
- if (!using_intermediate_buffer ||
- (anh_interleave != 1 || (anh_bits & anfXor) == 0))
- which = 1 - which;
-
- display_body (mystream, &opt,
- (struct BitMapHeader *)bmhdprop->sp_Data,
- (UBYTE *)cmapprop->sp_Data, width, height,
- oscan_height, depth, fname, which, intended_mode,
- &eclocks, &warp_eclocks, &next_time);
-
- totalframes++;
-
- }
-
- continue; /* file rewound, restart from while (going) */
-
- }
- } else if (ifferror != 0) {
- abort_anim ("IFF error %d parsing %s", ifferror, fname);
- }
-
- /* PrintTopChunk (iff); */
-
- if (PropChunk (iff, ID_ILBM, ID_ANHD) != 0 ||
- PropChunk (iff, ID_ILBM, ID_CMAP) != 0 ||
- StopChunk (iff, ID_ILBM, ID_DLTA) != 0)
- abort_anim ("Error calling PropChunk or StopChunk parsing %s", fname);
- if ((ifferror = ParseIFF (iff, IFFPARSE_SCAN)) != 0)
- abort_anim ("IFF error %d parsing %s", ifferror, fname);
- if ((anhdprop = FindProp (iff, ID_ILBM, ID_ANHD)) == NULL)
- abort_anim ("missing ANHD chunk parsing %s", fname);
-
- anhd = (struct AnimHeader *)anhdprop->sp_Data;
- anh_operation = anhd->anh_Operation;
- anh_interleave = anhd->anh_Interleave;
- anh_bits = anhd->anh_Bits;
- eclocks.ev_lo = (ULONG)((1000000.0 / 60.0) * anhd->anh_Reltime /
- micros_per_eclock + 0.5);
- add64 (&total_eclocks, &eclocks);
- if (first_time) {
- printf ("Anim type %d, abstime %ld, reltime %ld, anh_interleave %d, flags %08x\n",
- (int)anh_operation, anhd->anh_Abstime, anhd->anh_Reltime,
- (int)anh_interleave, anh_bits);
- first_time = FALSE;
- }
-
- size = CurrentChunk (iff)->cn_Size;
- /* printf ("DLTA size %d at %d\n", size, CurrentChunk (iff)->cn_Scan); */
- if (mystream->f != NULL) {
- dlta = malloc_check (size);
- if (ReadChunkBytes (iff, dlta, size) != size)
- abort_anim ("Error reading %s", fname);
- } else
- dlta = mystream->rambufptr;
-
- /* render to the other bitmap */
- if (!using_intermediate_buffer ||
- (anh_interleave != 1 || (anh_bits & anfXor) == 0))
- which = 1 - which;
-
- if (using_intermediate_buffer)
- memset (dirty, -1, (((bm[0]->BytesPerRow + 3) >> 2) << 1) * sizeof(WORD));
- else
- /* wait until beam has finished displaying bm[which] */
- wait_until_safe ();
-
- /* unpack DLTA to bm[which] */
- for (plane = 0; plane < depth; plane++) {
- wdata = (WORD *)&dlta[((ULONG *)dlta)[plane]];
- /* printf ("%d %08x %ld\n", plane, wdata, ((ULONG *)dlta)[plane]); */
-
- switch (anh_operation) {
-
- case cmpLongdelta: /* 2 */
- if (wdata != (WORD *)dlta)
- unpacklongdelta (wdata, (LONG *)bm[which]->Planes[plane],
- bm[which]->BytesPerRow, dirty);
- break;
-
- case cmpShortdelta: /* 3 */
- if (wdata != (WORD *)dlta)
- unpackshortdelta (wdata, (WORD *)bm[which]->Planes[plane],
- bm[which]->BytesPerRow, dirty);
- break;
-
- case cmpBytedelta: /* 5 */
- if (wdata != (WORD *)dlta)
- if (using_intermediate_buffer)
- if (anh_interleave == 1 && (anh_bits & anfXor) != 0)
- unpackbytedeltaxor ((BYTE *)wdata, bm[which]->Planes[plane],
- bm[which]->BytesPerRow, dirty);
- else
- unpackbytedelta ((BYTE *)wdata, bm[which]->Planes[plane],
- bm[which]->BytesPerRow, dirty);
- else
- if (anh_interleave == 1 && (anh_bits & anfXor) != 0)
- unpackbytedeltanodirtyxor ((BYTE *)wdata,
- bm[which]->Planes[plane],
- bm[1-which]->Planes[plane],
- bm[which]->BytesPerRow, height);
- else
- unpackbytedeltanodirty ((BYTE *)wdata, bm[which]->Planes[plane],
- bm[which]->BytesPerRow);
- break;
-
- case cmpAnim7: /* 7 */
- if (wdata != (WORD *)dlta)
- if ((anh_bits & anfLongdata) != 0)
- if (using_intermediate_buffer)
- unpackanim7long ((BYTE *)wdata,
- (LONG *)&dlta[((ULONG *)dlta)[plane + 8]],
- bm[which]->Planes[plane],
- bm[which]->BytesPerRow,
- dirty);
- else
- unpackanim7longnodirty ((BYTE *)wdata,
- (LONG *)&dlta[((ULONG *)dlta)[plane + 8]],
- bm[which]->Planes[plane],
- bm[which]->BytesPerRow);
- else
- if (using_intermediate_buffer)
- unpackanim7word ((BYTE *)wdata,
- (WORD *)&dlta[((ULONG *)dlta)[plane + 8]],
- bm[which]->Planes[plane],
- bm[which]->BytesPerRow,
- dirty);
- else
- unpackanim7wordnodirty ((BYTE *)wdata,
- (WORD *)&dlta[((ULONG *)dlta)[plane + 8]],
- bm[which]->Planes[plane],
- bm[which]->BytesPerRow);
- break;
-
- case cmpAnim8: /* 8 */
- if (wdata != (WORD *)dlta)
- if ((anh_bits & anfLongdata) != 0)
- if (using_intermediate_buffer)
- unpackanim8long ((LONG *)wdata,
- bm[which]->Planes[plane],
- bm[which]->BytesPerRow,
- dirty);
- else
- unpackanim8longnodirty ((LONG *)wdata,
- bm[which]->Planes[plane],
- bm[which]->BytesPerRow);
- else
- if (using_intermediate_buffer)
- unpackanim8word ((WORD *)wdata,
- bm[which]->Planes[plane],
- bm[which]->BytesPerRow,
- dirty);
- else
- unpackanim8wordnodirty ((WORD *)wdata,
- bm[which]->Planes[plane],
- bm[which]->BytesPerRow);
- break;
-
- case cmpDirect: /* 0 */
- case cmpXor: /* 1 */
- case cmpDelta: /* 4 */
- case cmpStereo: /* 6 */
- case cmpJ: /* 74 */
- default:
- abort_anim ("Anim type %d not recognised", (int)anh_operation);
- }
- }
-
- if (mystream->f != NULL)
- free (dlta);
-
- if (using_intermediate_buffer) {
-
- /* wait until beam has passed displayable bitmap for bm[which] */
- wait_until_safe ();
-
- /* copy bm[which] to its displayable bitmap (if bm[] not displayable) */
- if (using_changescreenbuffer) {
- saved_bm = w->RPort->BitMap;
- w->RPort->BitMap = sb[which]->sb_BitMap;
- }
- if (anh_operation == cmpBytedelta ||
- anh_operation == cmpAnim7 ||
- anh_operation == cmpAnim8)
- blit_opt (bm[which], w->RPort, dirty,
- which == 0 || using_changescreenbuffer ? 0 : oscan_height);
- else
- BltBitMapRastPort (bm[which], 0, 0, w->RPort, 0,
- which == 0 || using_changescreenbuffer ? 0 : oscan_height,
- width, height, 0xc0);
- if (using_changescreenbuffer) {
- w->RPort->BitMap = saved_bm;
- }
- }
-
- /* calculate colourtable if required */
- if ((cmapprop = FindProp (iff, ID_ILBM, ID_CMAP)) != NULL)
- colourtable = calc_cmap (s, (UBYTE *)cmapprop->sp_Data, 1 << depth,
- intended_mode);
-
- /* wait for time between frames */
- delay_until (&next_time);
- if (opt.warp)
- add64 (&next_time, &warp_eclocks);
- else
- add64 (&next_time, &eclocks);
-
- /* temporarily increase priority to reduce palette change flicker */
- oldpri = SetTaskPri (FindTask(NULL), 20);
-
- /* wait until previous frame has been displayed */
- if (using_changescreenbuffer)
- wait_until_disp ();
-
- /* load colourtable */
- if (cmapprop != NULL)
- LoadRGB32 (&s->ViewPort, colourtable);
-
- /* make bm[which] (or its associated displayable bitmap) visible */
- if (using_changescreenbuffer) {
- if (ChangeScreenBuffer (s, sb[which]) != 0) {
- disp = FALSE;
- safe = FALSE;
- }
- } else {
- /* MoveScreen (s, which != 0 ? oscan_height : -oscan_height, 0); */
- s->ViewPort.RasInfo->RyOffset = which != 0 ? oscan_height : 0;
- ScrollVPort (&s->ViewPort);
- }
- waited_until_safe = FALSE;
-
- /* restore task priority */
- SetTaskPri (FindTask(NULL), oldpri);
-
- if (cmapprop != NULL)
- free (colourtable);
-
- totalframes++;
-
- } /* end of loop for each frame */
-
- /* find out and display how long it took */
- ReadEClock (time1);
- if (total_eclocks.ev_hi != 0 || total_eclocks.ev_lo != 0)
- printf ("%s: Intended frames per second = %4.1lf\n", programname,
- 1000000.0 * totalframes /
- ((total_eclocks.ev_hi * 4294967296.0 + total_eclocks.ev_lo) *
- micros_per_eclock));
- sub64 (time1, time0);
- printf ("%s: Achieved frames per second = %4.1lf\n", programname,
- 1000000.0 * totalframes /
- ((time1->ev_hi * 4294967296.0 + time1->ev_lo) * micros_per_eclock));
-
- partial_cleanup ();
- }
-
- /****************************************************************************/
-
- static void filerequestloop (struct options *opt)
- {
- static char resultstring[128];
-
- if (AslBase != NULL) {
- while (AslRequest (fr, NULL)) {
- strcpy (resultstring, fr->rf_Dir);
- AddPart (resultstring, fr->rf_File, 128);
- animate_file (resultstring, *opt);
- }
- }
- }
-
- /****************************************************************************/
-
- static LONG argarray[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
- int main (int argc, char *argv[])
- {
- struct WBStartup *argmsg;
- struct WBArg *wb_arg;
- char **fnames;
- UWORD ktr;
- struct options opt;
-
- if (atexit (cleanup) != 0)
- die ("Can't install exit handler");
-
- GetProgramName (programname, 19);
-
- CyberGfxBase = OpenLibrary ("cybergraphics.library", 0);
-
- if ((IFFParseBase = OpenLibrary ("iffparse.library", 0)) == NULL)
- die ("Can't open iff.library");
-
- if ((AslBase = (struct Library *)OpenLibrary ("asl.library", 38L)) == NULL)
- die ("Can't open asl.library v38");
-
- if ((fr = (struct FileRequester *)AllocAslRequestTags (ASL_FileRequest,
- ASL_Hail, (ULONG)programname,
- ASL_Pattern, (ULONG)"~(#?.info)",
- ASL_OKText, (ULONG)"Play",
- ASL_CancelText, (ULONG)"Cancel",
- ASL_FuncFlags, FILF_PATGAD,
- TAG_DONE)) == NULL)
- die ("Can't allocate file requester");
-
- if ((smr = AllocAslRequestTags (ASL_ScreenModeRequest, TAG_DONE)) == NULL)
- die ("Can't allocate screenmode requester");
-
- /* timer stuff */
- if ((timermp = CreatePort (NULL, 0)) == NULL)
- die ("Can't create messageport!");
- if ((timerio = (struct timerequest *)CreateExtIO (timermp,
- sizeof(struct timerequest))) == NULL)
- die ("Can't create External IO!");
- if (timerclosed = OpenDevice (TIMERNAME, UNIT_ECLOCK,
- (struct IORequest *)timerio, 0))
- die ("Can't open timer.device!");
- TimerBase = (struct Library *)timerio->tr_node.io_Device;
- if ((time = (struct EClockVal *)AllocMem (sizeof(struct EClockVal),
- MEMF_CLEAR | MEMF_PUBLIC)) == NULL ||
- (time0 = (struct EClockVal *)AllocMem (sizeof(struct EClockVal),
- MEMF_CLEAR | MEMF_PUBLIC)) == NULL ||
- (time1 = (struct EClockVal *)AllocMem (sizeof(struct EClockVal),
- MEMF_CLEAR | MEMF_PUBLIC)) == NULL)
- die ("Out of memory");
- micros_per_eclock = 1000000.0 / (double)ReadEClock (time);
-
- /* more timer stuff */
- if ((timermp2 = CreatePort (NULL, 0)) == NULL)
- die ("Can't create messageport!");
- if ((timerio2 = (struct timerequest *)CreateExtIO (timermp2,
- sizeof(struct timerequest))) == NULL)
- die ("Can't create External IO!");
- if (timer2closed = OpenDevice (TIMERNAME, UNIT_VBLANK,
- (struct IORequest *)timerio2, 0))
- die ("Can't open timer.device!");
-
- opt.ram = TRUE;
- opt.once = FALSE;
- opt.dbuf = TRUE;
- opt.warp = FALSE;
- opt.modereq = TRUE;
- opt.waittof = FALSE;
- opt.waitbovp = FALSE;
- opt.changescreenbuffer = FALSE;
- opt.loopframes = TRUE;
- opt.mode = INVALID_ID;
-
- /* parse workbench message or commandline */
- if (argc == 0) {
- argmsg = (struct WBStartup *)argv;
- wb_arg = argmsg->sm_ArgList;
- strcpy (programname, wb_arg->wa_Name);
- parse_tooltypes (wb_arg->wa_Name, &opt);
- if (argmsg->sm_NumArgs <= 1)
- filerequestloop (&opt);
- else {
- wb_arg++;
- for (ktr = 1; ktr < argmsg->sm_NumArgs; ktr++, wb_arg++)
- if (wb_arg->wa_Lock != NULL) {
- olddir = CurrentDir (wb_arg->wa_Lock);
- animate_file (wb_arg->wa_Name, opt);
- CurrentDir (olddir);
- olddir = NULL;
- } else
- animate_file (wb_arg->wa_Name, opt);
- }
- } else {
- if ((rdargs = ReadArgs
- ("FILE/M,DISK/S,RAM/S,ONCE/S,WARP/S,NOMODEREQ/S,WAITTOF/S,WAITBOVP/S,CH=CHANGESCREENBUFFER/S,NOLOOPFRAMES/S,SC=SCREENMODE/K",
- argarray, NULL)) != NULL) {
- chkabort ();
- if (argarray[1])
- opt.ram = FALSE;
- if (argarray[2])
- opt.ram = TRUE;
- if (argarray[3])
- opt.once = TRUE;
- if (argarray[4])
- opt.warp = TRUE;
- if (argarray[5])
- opt.modereq = FALSE;
- if (argarray[6])
- opt.waittof = TRUE;
- if (argarray[7])
- opt.waitbovp = TRUE;
- if (argarray[8])
- opt.changescreenbuffer = TRUE;
- if (argarray[9])
- opt.loopframes = FALSE;
- if (argarray[10] != NULL)
- opt.mode = parse_mode ((char *)argarray[10]);
- fnames = (char **)argarray[0];
- if (fnames == NULL || *fnames == NULL)
- filerequestloop (&opt);
- else
- while (*fnames != NULL)
- animate_file (*fnames++, opt);
- FreeArgs (rdargs);
- rdargs = NULL;
- }
- }
-
- return (0);
- }
-
- /****************************************************************************/
-